﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.IO;


namespace CardMonitor.Utils
{
  

        /// <summary>
        /// 身份证读卡器操作类（适配sdtapi.dll）
        /// 路径：D:\客户端代码\富洲\工控机代码1126集成车牌识别\LocalServer\dlls\Sdtapi.dll
        /// </summary>
        public sealed class NewIdCardReader
        {
            #region DLL常量定义
            private const string DLL_PATH = @"D:\客户端代码\富洲\工控机代码1126集成车牌识别\LocalServer\dlls\Sdtapi.dll";
            private const CallingConvention CALL_CONVENTION = CallingConvention.StdCall;
            private const int DEFAULT_PORT = 1001; // USB端口
            private const int ID_OFFSET = 122;     // 身份证号起始偏移（根据协议调整）
            private const int ID_LENGTH = 19;

            #endregion

            #region DLL函数声明

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int InitComm(int iPort);

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int CloseComm();

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int Authenticate();

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int Routon_IC_FindCard();//本函数用于寻卡。

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int Routon_IC_HL_ReadCardSN(byte[] SN);//本函数用于读取IC卡的序列号，自动完成找卡、选卡等过程。

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int Routon_IC_HL_ReadCard(int SID, int BID, int KeyType, byte[] Key, byte[] data);//函数用于读取IC卡指定扇区的数据内容，在调用本函数前需要先找卡Routon_IC_FindCard()

            [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int ReadBaseInfos(
                StringBuilder Name,
                StringBuilder Gender,
                StringBuilder Folk,
                StringBuilder BirthDay,
                StringBuilder Code,
                StringBuilder Address,
                StringBuilder Agency,
                StringBuilder ExpireStart,
                StringBuilder ExpireEnd

            );
        [DllImport("Dll/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Routon_ReadAllBaseInfos(
      StringBuilder Msg,
      byte[] HeadPhoto,
      byte[] FrontCopy,
      byte[] BackCopy,
      byte[] FingerPrint
  );


        [DllImport("dlls/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern int ReadIINSNDN(StringBuilder pMsg);
            /*        [DllImport("dlls/Sdtapi.dll")]
                    public static extern int InitComm(int iPort);


                    [DllImport("dlls/Sdtapi.dll")]
                    public static extern int CloseComm();

                    // ---------------------- 读卡操作 ----------------------
                    [DllImport("dlls/Sdtapi.dll")]
                    public static extern int Authenticate();*/

            [DllImport("dlls/Sdtapi.dll")]
            public static extern int ReadBaseMsg(
                [Out] byte[] pMsg,
                ref int len
            );

            [DllImport("dlls/Sdtapi.dll")]
            public static extern int ReadIINSNDN(
                [Out] byte[] pucRecvData
            );

            // ---------------------- 错误处理 ----------------------
            /*   [DllImport("dlls/Sdtapi.dll")]
               public static extern int SDT_GetErrorString(
                   int ErrorCode,
                   [Out] StringBuilder ErrorString
               );*/
            #endregion

            #region 状态管理
            /// <summary>
            /// 当前使用的读卡器端口号（默认1001=USB）
            /// </summary>
            public int PortId { get; } = 1001;

            /// <summary>
            /// 端口是否已初始化
            /// </summary>
            public bool IsInitialized { get; private set; }
            #endregion

            #region 核心方法
            /// <summary>
            /// 初始化读卡器端口
            /// </summary>
            public void Initialize()
            {
                if (IsInitialized) return;

                int result = InitComm(PortId);
                if (result != 0)
                {
                    ThrowCardReaderException(result);
                }
                IsInitialized = true;
            }

            /// <summary>
            /// 读取身份证文字信息
            /// </summary>
            /// <returns>GB2312编码的身份证信息</returns>
            public string ReadBaseInfo()
            {
                CheckInitialization();

                byte[] buffer = new byte[256];
                int len = buffer.Length;

                int result = ReadBaseMsg(buffer, ref len);
                if (result != 0)
                {
                    ThrowCardReaderException(result);
                }

                return Encoding.GetEncoding("GB2312").GetString(buffer, 0, len);
            }

            /// <summary>
            /// 读取身份证号和物理卡号
            /// </summary>
            public (string IdNumber, string CardNumber) ReadCardNumbers()
            {
                CheckInitialization();

                byte[] buffer = new byte[192]; // 根据协议文档确定长度
                int result = ReadIINSNDN(buffer);
                if (result != 0)
                {
                    ThrowCardReaderException(result);
                }

                return (

                    Encoding.ASCII.GetString(buffer, 122, 19).TrimEnd('\0'),
                    //idNumber,
                    Encoding.ASCII.GetString(buffer, 0, 19).TrimEnd('\0')
                );
            }
            #endregion

            public string Readcard()
            {
                //  char buffer[256];
                byte[] buffer = new byte[256];
                int len = 300;
                int result = ReadBaseMsg(buffer, ref len);
                if (result != 1) // 假设1表示成功
                {
                    throw new Exception($"读取失败，错误码: {result}");
                }
                // 3. 调试输出原始数据（十六进制格式）
                Console.WriteLine("原始数据: " + BitConverter.ToString(buffer, 0, len));

                // 4. 根据协议解析身份证号（示例参数，需按实际设备调整）
                int idNumberOffset = 122; // 身份证号起始位置（字节索引）
                int idNumberLength = 19;  // 身份证号长度（18位数字 + 1字节终止符）

                // 5. 提取并转换数据（使用正确编码）
                string idNumber = Encoding.GetEncoding("GB2312") // 或 ASCII/其他编码
                                         .GetString(buffer, idNumberOffset, idNumberLength)
                                         .TrimEnd('\0'); // 去除终止符

                return idNumber;


            }
            #region 错误处理
            private void ThrowCardReaderException(int errorCode)
            {
                /* var sb = new StringBuilder(256);
                 SDT_GetErrorString(errorCode, sb);
                 throw new IdReaderException(errorCode, sb.ToString());*/
            }

            /// <summary>
            /// 自定义身份证读卡器异常
            /// </summary>
            public class IdReaderException : Exception
            {
                public int ErrorCode { get; }

                public IdReaderException(int code, string message)
                    : base($"身份证读卡器错误 {code:X8}: {message}")
                {
                    ErrorCode = code;
                }
            }
            #endregion

            #region 资源清理
            public void Dispose()
            {
                if (IsInitialized)
                {
                    CloseComm();
                    IsInitialized = false;
                }
            }

            private void CheckInitialization()
            {
                if (!IsInitialized)
                {
                    throw new InvalidOperationException("请先调用Initialize()初始化端口");
                }
            }
       /* public static CardInfoNew IDread()
        {
            CardInfoNew objCardInfonew = null;
            string idNumber=null;
            // 分配足够的内存
            const int MSG_BUFFER_SIZE = 256;
            const int PHOTO_BUFFER_SIZE = 100 * 1024; // 100KB
            const int COPY_BUFFER_SIZE = 200 * 1024; // 200KB
            const int FINGERPRINT_BUFFER_SIZE = 1024;

            StringBuilder msgBuffer = new StringBuilder(MSG_BUFFER_SIZE);
            byte[] headPhotoBuffer = new byte[PHOTO_BUFFER_SIZE];
            byte[] frontCopyBuffer = new byte[COPY_BUFFER_SIZE];
            byte[] backCopyBuffer = new byte[COPY_BUFFER_SIZE];
            byte[] fingerprintBuffer = new byte[FINGERPRINT_BUFFER_SIZE];

            // 调用函数
            int result = Routon_ReadAllBaseInfos(
                msgBuffer,
                headPhotoBuffer,
                frontCopyBuffer,
                backCopyBuffer,
                fingerprintBuffer
            );

            if (result == 1)
            {
                // 成功读取
                Console.WriteLine("读取成功");

                // 提取身份证号
                string msg = msgBuffer.ToString();
                string[] fields = msg.Split(':');
                if (fields.Length >= 10)
                {
                     idNumber = fields[9]; // 身份证号码通常在第10个字段
                    Console.WriteLine($"身份证号: {idNumber}");
                }

                // 处理照片数据（Base64编码）
                string headPhotoBase64 = Convert.ToBase64String(headPhotoBuffer);
                string frontCopyBase64 = Convert.ToBase64String(frontCopyBuffer);
                string backCopyBase64 = Convert.ToBase64String(backCopyBuffer);

                // 你可以将Base64字符串保存为文件或其他处理
                // 例如，保存为文件：
                //File file = new File();
                 File.WriteAllBytes("c:\\azp.bmp", Convert.FromBase64String(headPhotoBase64));
                objCardInfonew.CardNo = idNumber;
            }
            else
            {
                Console.WriteLine($"读取失败，错误代码: {result}");
            }
        }*/
            #endregion
            public string ReadIdNumber()
            {
                // 初始化端口
                if (InitComm(DEFAULT_PORT) != 1)
                    throw new Exception("端口初始化失败");

                try
                {
                    // 认证身份证
                    /*   if (Authenticate() != 1)
                           throw new Exception("身份证认证失败");*/

                    // 读取原始数据
                    byte[] buffer = new byte[256]; // 足够大的缓冲区
                    int len = buffer.Length;
                    /*              if (ReadBaseMsg(buffer, ref len) != 1)
                                      throw new Exception("数据读取失败");*/

                    // 解析身份证号（GB2312编码）
                    return Encoding.GetEncoding("GB2312")
                        .GetString(buffer, ID_OFFSET, ID_LENGTH)
                        .TrimEnd('\0');
                }
                finally
                {
                    CloseComm(); // 确保关闭端口
                }
            }


        
    }
    public class CardInfoNew
    {

        public string Id;
        /// <summary>
        /// 身份证号码
        /// </summary>
        public string CardNo;
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name;
       
    }


}
